#include "GY_MutuallyExclusiveGroup.h"
#include <QDebug>

GY_MutuallyExclusiveGroup::GY_MutuallyExclusiveGroup(const QString &guid, QGraphicsItem *parent) : GY_ContainerTransform(guid,this, parent)
{
    initializationPropertyInfo();
    this->setCenterPointF(m_PropertyInfoMap["Position"].propertyValue.toPointF());
}

bool GY_MutuallyExclusiveGroup::addItem(GY_Object *pItem)
{
    if(pItem->inherits("GY_BasicsGraphicsObject"))
    {
        this->addToGroup((GY_BasicsGraphicsObject*)pItem);
    }
    else if(pItem->inherits("GY_ContainerTransform"))
    {
        this->addToGroup((GY_ContainerTransform*)pItem);
    }
    else
    {
        return false;
    }
    m_OrderChildrens.append(pItem);
    m_ChildrensMap.insert(pItem->getGuid(),pItem);
    m_PropertyInfoMap["NumChildren"].propertyValue = m_OrderChildrens.size();
    return true;
}

bool GY_MutuallyExclusiveGroup::removItem(const QString &guid)
{
    if(!m_ChildrensMap.contains(guid))
    {
        return false;
    }
    m_ChildrensMap.remove(guid);
    return true;
}

bool GY_MutuallyExclusiveGroup::removItem(const GY_Object *pItem)
{
    if(pItem->inherits("GY_BasicsGraphicsObject"))
    {
        this->removeFromGroup((GY_BasicsGraphicsObject*)pItem);
    }
    else if(pItem->inherits("GY_ContainerTransform"))
    {
        this->removeFromGroup((GY_ContainerTransform*)pItem);
    }
    else
    {
        return false;
    }
    m_OrderChildrens.removeOne((GY_Object *)pItem);
    m_PropertyInfoMap["NumChildren"].propertyValue = m_OrderChildrens.size();
    return  removItem(pItem->getGuid());
}

void GY_MutuallyExclusiveGroup::initializationPropertyInfo()
{
    GY_PropertyInfo ObjectName(this);
    ObjectName.propertyName = "ObjectName";
    ObjectName.propertyValue = QString();
    ObjectName.updateType = Update|OrdinaryAttributes;
    ObjectName.propertyType = QStringPropertyType;
    ObjectName.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_MutuallyExclusiveGroup::updateObjectName;
    m_PropertyInfoMap.insert("ObjectName",ObjectName);
    m_PropertyInfoMap[ObjectName.propertyName].setConnect();

    //位置
    GY_PropertyInfo positonPropertyInfo(this);
    positonPropertyInfo.propertyName="Position";
    positonPropertyInfo.propertyValue=QPointF(0,0);
    positonPropertyInfo.updateType = Update|MoveUpdate|PointOfRelative;
    positonPropertyInfo.propertyType = PointPropertyType;
    positonPropertyInfo.updatePropertyFun=(GY_PropertyInfo::UpdatePropertyFun)&GY_MutuallyExclusiveGroup::updatePosition;
    m_PropertyInfoMap.insert(positonPropertyInfo.propertyName,positonPropertyInfo);
    m_PropertyInfoMap[positonPropertyInfo.propertyName].setConnect();

    GY_PropertyInfo visibleChildPropertyInfo(this);
    visibleChildPropertyInfo.propertyName="VisibleChild";
    visibleChildPropertyInfo.propertyValue=0;
    visibleChildPropertyInfo.updateType = Update|OrdinaryAttributes;
    visibleChildPropertyInfo.propertyType = UshortPropertyType;
    visibleChildPropertyInfo.updatePropertyFun=(GY_PropertyInfo::UpdatePropertyFun)&GY_MutuallyExclusiveGroup::updateVisibleChild;
    m_PropertyInfoMap.insert(visibleChildPropertyInfo.propertyName,visibleChildPropertyInfo);
    m_PropertyInfoMap[visibleChildPropertyInfo.propertyName].setConnect();

    GY_PropertyInfo showAllChildrenPropertyInfo(this);
    showAllChildrenPropertyInfo.propertyName="ShowAllChildren";
    showAllChildrenPropertyInfo.propertyValue=false;
    showAllChildrenPropertyInfo.updateType = Update|OrdinaryAttributes;
    showAllChildrenPropertyInfo.propertyType = BoolPropertyType;
    showAllChildrenPropertyInfo.updatePropertyFun=(GY_PropertyInfo::UpdatePropertyFun)&GY_MutuallyExclusiveGroup::updateShowAllChildren;
    m_PropertyInfoMap.insert(showAllChildrenPropertyInfo.propertyName,showAllChildrenPropertyInfo);
    m_PropertyInfoMap[showAllChildrenPropertyInfo.propertyName].setConnect();

    GY_PropertyInfo numChildrenPropertyInfo(this);
    numChildrenPropertyInfo.propertyName="NumChildren";
    numChildrenPropertyInfo.propertyValue=0;
    numChildrenPropertyInfo.updateType = Update|OrdinaryAttributes;
    numChildrenPropertyInfo.propertyType = UshortPropertyType;
    numChildrenPropertyInfo.updatePropertyFun=(GY_PropertyInfo::UpdatePropertyFun)&GY_MutuallyExclusiveGroup::updateNumChildren;
    m_PropertyInfoMap.insert(numChildrenPropertyInfo.propertyName,numChildrenPropertyInfo);
    m_PropertyInfoMap[numChildrenPropertyInfo.propertyName].setConnect();

    GY_PropertyInfo updateVisibleChildOnlyPropertyInfo(this);
    updateVisibleChildOnlyPropertyInfo.propertyName="UpdateVisibleChildOnly";
    updateVisibleChildOnlyPropertyInfo.propertyValue=false;
    updateVisibleChildOnlyPropertyInfo.updateType = Update|OrdinaryAttributes;
    updateVisibleChildOnlyPropertyInfo.propertyType = BoolPropertyType;
    updateVisibleChildOnlyPropertyInfo.updatePropertyFun=(GY_PropertyInfo::UpdatePropertyFun)&GY_MutuallyExclusiveGroup::updateUpdateVisibleChildOnly;
    m_PropertyInfoMap.insert(updateVisibleChildOnlyPropertyInfo.propertyName,updateVisibleChildOnlyPropertyInfo);
    m_PropertyInfoMap[updateVisibleChildOnlyPropertyInfo.propertyName].setConnect();

}

bool GY_MutuallyExclusiveGroup::updatePosition(const QString &name, const QVariant &value)
{
    if(!value.canConvert<QPointF>())
    {
        return false;
    }
    //setpos设置为父级坐标
    QPointF point = value.toPointF();
    if(this->parentItem()) {
        point = this->mapToParent(this->mapFromScene(value.toPointF()));
    }
    this->setPos(point);
    m_PropertyInfoMap[name].propertyValue=this->mapFromScene(value.toPointF());
    return true;
}

bool GY_MutuallyExclusiveGroup::updateVisibleChild(const QString &name, const QVariant &value)
{
    if(!value.canConvert<ushort>())
    {
        return false;
    }
    int m_OrderChildrensSize = m_OrderChildrens.size();
    if(value.toUInt()>(uint)m_OrderChildrensSize) {
        m_PropertyInfoMap[name].propertyValue=(uint)m_OrderChildrensSize;
    }else {
        m_PropertyInfoMap[name].propertyValue=value.toUInt();
    }
    if(!m_PropertyInfoMap["ShowAllChildren"].propertyValue.toBool()) {
        for(int i = 0; i<m_OrderChildrensSize; i++) {
            hideItem(i);
        }
        showChildrenItem(m_PropertyInfoMap[name].propertyValue.toUInt()-1);
    }
    return true;
}

bool GY_MutuallyExclusiveGroup::updateNumChildren(const QString &, const QVariant &)
{

    return false;
}

bool GY_MutuallyExclusiveGroup::updateShowAllChildren(const QString &name, const QVariant &value)
{
    if(!value.canConvert<bool>())
    {
        return false;
    }
    int m_OrderChildrensSize = m_OrderChildrens.size();
    m_PropertyInfoMap[name].propertyValue=value.toBool();
    if(value.toBool()) {
        for(int i = 0; i<m_OrderChildrensSize; i++) {
            showChildrenItem(i);
        }
    }else {
        for(int i = 0; i<m_OrderChildrensSize; i++) {
            hideItem(i);
        }
        showChildrenItem(m_PropertyInfoMap["VisibleChild"].propertyValue.toUInt()-1);
    }
    return true;
}

bool GY_MutuallyExclusiveGroup::updateUpdateVisibleChildOnly(const QString &name, const QVariant &value)
{
    if(!value.canConvert<bool>())
    {
        return false;
    }
    m_PropertyInfoMap[name].propertyValue=value.toBool();

    return true;
}

void GY_MutuallyExclusiveGroup::showChildrenItem(const int &index)
{
    if(index < 0) {
        return;
    }
    GY_Object *pItem = m_OrderChildrens.at(index);
    //查找是否存在IsVisible属性
    bool isVisibleProperty;
    QMap<QString, GY_PropertyInfo> map = pItem->getPropertyMap();
    if(map.contains("IsVisible")) {
        isVisibleProperty = map["IsVisible"].propertyValue.toBool();
    }else {
        isVisibleProperty = true;
    }
    if(pItem->inherits("GY_BasicsGraphicsObject"))
    {
        ((GY_BasicsGraphicsObject*)pItem)->setVisible(isVisibleProperty);
    }
    else if(pItem->inherits("GY_ContainerTransform"))
    {
        ((GY_ContainerTransform*)pItem)->setVisible(isVisibleProperty);
    }
}

void GY_MutuallyExclusiveGroup::hideItem(const int &index)
{
    if(index < 0) {
        return;
    }
    GY_Object *pItem = m_OrderChildrens.at(index);
    if(pItem->inherits("GY_BasicsGraphicsObject"))
    {
        ((GY_BasicsGraphicsObject*)pItem)->setVisible(false);
    }
    else if(pItem->inherits("GY_ContainerTransform"))
    {
        ((GY_ContainerTransform*)pItem)->setVisible(false);
    }
}




